home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / xgrasp.zip / PARSER.C < prev    next >
C/C++ Source or Header  |  1991-07-24  |  7KB  |  354 lines

  1. #ident "@(#)parser.c    1.8 91/04/01 XGRASP"
  2. /*-
  3.  * parser.c - grasp language file parser.
  4.  *
  5.  * Copyright (c) 1991 by Patrick J. Naughton
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and its
  8.  * documentation for any purpose and without fee is hereby granted,
  9.  * provided that the above copyright notice appear in all copies and that
  10.  * both that copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * This file is provided AS IS with no warranties of any kind.  The author
  14.  * shall have no liability with respect to the infringement of copyrights,
  15.  * trade secrets or any patents by this file or any part thereof.  In no
  16.  * event will the author be liable for any lost revenue or profits or
  17.  * other special, indirect and consequential damages.
  18.  *
  19.  * Comments and additions should be sent to the author:
  20.  *
  21.  *                     Patrick J. Naughton
  22.  *                     Sun Microsystems
  23.  *                     2550 Garcia Ave, MS 10-20
  24.  *                     Mountain View, CA 94043
  25.  *                     (415) 336-1080
  26.  *
  27.  */
  28.  
  29. #include "grasp.h"
  30.  
  31. char       *tokens[] = {
  32.     "notoken",
  33.     "box",
  34.     "break",
  35.     "call",
  36.     "cfade",
  37.     "cfree",
  38.     "cgetbuf",
  39.     "chgcolor",
  40.     "circle",
  41.     "clearscr",
  42.     "cload",
  43.     "closegl",
  44.     "color",
  45.     "cycle",
  46.     "data",
  47.     "databegin",
  48.     "dataend",
  49.     "dataskip",
  50.     "dfree",
  51.     "dload",
  52.     "edge",
  53.     "else",
  54.     "endlfloat",
  55.     "endif",
  56.     "exec",
  57.     "exit",
  58.     "ffree",
  59.     "fgaps",
  60.     "fload",
  61.     "float",
  62.     "fly",
  63.     "font",
  64.     "fstyle",
  65.     "getcolor",
  66.     "getkey",
  67.     "gosub",
  68.     "goto",
  69.     "if",
  70.     "ifkey",
  71.     "ifmem",
  72.     "ifmouse",
  73.     "ifvideo",
  74.     "int",
  75.     "line",
  76.     "link",
  77.     "local",
  78.     "loop",
  79.     "mark",
  80.     "merge",
  81.     "mode",
  82.     "mouse",
  83.     "move",
  84.     "noise",
  85.     "note",
  86.     "offset",
  87.     "opengl",
  88.     "out",
  89.     "palette",
  90.     "pan",
  91.     "pfade",
  92.     "pfree",
  93.     "pgetbuf",
  94.     "pload",
  95.     "pnewbuf",
  96.     "point",
  97.     "poke",
  98.     "pokel",
  99.     "pokew",
  100.     "pop",
  101.     "position",
  102.     "psave",
  103.     "psetbuf",
  104.     "putoff",
  105.     "putup",
  106.     "rect",
  107.     "resetgl",
  108.     "resetscr",
  109.     "return",
  110.     "revpage",
  111.     "send",
  112.     "set",
  113.     "setcolor",
  114.     "setpage",
  115.     "setrgb",
  116.     "setupscr",
  117.     "split",
  118.     "spread",
  119.     "text",
  120.     "tile",
  121.     "timer",
  122.     "tran",
  123.     "video",
  124.     "waitkey",
  125.     "when",
  126.     "window",
  127.     "fade",
  128.     "wait",
  129. };
  130.  
  131. static char *
  132. sows(ptr)
  133.     char       *ptr;
  134. {
  135.     int         incomment = 0;
  136.  
  137.     while (incomment || *ptr == ' ' || *ptr == '\t' || *ptr == '\r' ||
  138.         *ptr == ',' || *ptr == ';') {
  139.     if (*ptr == ';')
  140.         incomment = 1;
  141.     else if (*ptr == '\n')
  142.         break;
  143.     ptr++;
  144.     }
  145.     return ptr;
  146. }
  147.  
  148. static char *
  149. sowsanl(ptr)
  150.     char       *ptr;
  151. {
  152.     int         incomment = 0;
  153.  
  154.     while (incomment || *ptr == ' ' || *ptr == '\t' || *ptr == '\r' ||
  155.         *ptr == ',' || *ptr == ';' || *ptr == '\n') {
  156.     if (*ptr == ';')
  157.         incomment = 1;
  158.     else if (*ptr == '\n')
  159.         incomment = 0;
  160.     ptr++;
  161.     }
  162.     return ptr;
  163. }
  164.  
  165. static char *
  166. copytoken(src, dst)
  167.     char       *src;
  168.     char       *dst;
  169. {
  170.     src = sowsanl(src);
  171.     if (*src == '"') {
  172.     src++;
  173.     while (*src != '"' && *src != '\n' && *src != '\r')
  174.         *dst++ = *src++;
  175.     if (*src != '\n')
  176.         src++;
  177.     } else
  178.     while (*src != ' ' && *src != '\t' && *src != '\r' &&
  179.         *src != ',' && *src != '\n' && *src != 26) {
  180.         if (*src >= 'A' && *src <= 'Z')
  181.         *dst++ = *src++ + 'a' - 'A';    /* tolower */
  182.         else
  183.         *dst++ = *src++;
  184.     }
  185.     *dst = 0;
  186.     src = sows(src);
  187.     return src;
  188. }
  189.  
  190. static int
  191. lookuptoken(ptr)
  192.     char       *ptr;
  193. {
  194.     int         i;
  195.  
  196.     if (ptr[strlen(ptr) - 1] != ':')
  197.     for (i = 1; i < NTOKENS; i++)
  198.         if (!strcmp(ptr, tokens[i]))
  199.         return i;
  200.  
  201.     return NOTOKEN;
  202. }
  203.  
  204. static int
  205. tokentoint(s, ret)
  206.     char       *s;
  207.     int        *ret;
  208. {
  209.     int         i;
  210.     for (i = 0; i < strlen(s); i++)
  211.     if (!isdigit(s[i]) && s[i] != '-')
  212.         return 0;
  213.     sscanf(s, "%d", ret);
  214.     return 1;
  215. }
  216.  
  217. static void
  218. addlabel(ex, s)
  219.     ExecStruct *ex;
  220.     char       *s;
  221. {
  222.     ex->label[ex->numlabels].string = strdup(s);
  223.     ex->label[ex->numlabels].ipaddr = ex->numcodes;
  224.     if (++(ex->numlabels) >= MAXLABELS)
  225.     error("%s: too many labels!");
  226. }
  227.  
  228. static void
  229. addargcount(ex, tokenaddr)
  230.     ExecStruct *ex;
  231.     int         tokenaddr;
  232. {
  233.     ex->Code[tokenaddr].val.i = ex->numcodes - tokenaddr - 1;
  234. }
  235.  
  236. static void
  237. addtoken(ex, t)
  238.     ExecStruct *ex;
  239.     int         t;
  240. {
  241.     ex->Code[ex->numcodes].token = t;
  242.     if (++(ex->numcodes) >= MAXCODES)
  243.     error("%s: text file too large. can only have %d tokens\n", MAXCODES);
  244. }
  245.  
  246. static void
  247. addstring(ex, string)
  248.     ExecStruct *ex;
  249.     char       *string;
  250. {
  251.     ex->Code[ex->numcodes].val.s = strdup(string);
  252.     addtoken(ex, STRING);
  253. }
  254.  
  255. static void
  256. addint(token, arg, ex, string, integer)
  257.     int         token;
  258.     int         arg;
  259.     ExecStruct *ex;
  260.     char       *string;
  261.     int         integer;
  262. {
  263.     /*
  264.      * make sure we don't convert a string that happens to parse as a number
  265.      * such as a filename, or keyname, or video mode, into an integer
  266.      */
  267.     if (((token == CLOAD || token == PLOAD || token == FLOAD)
  268.      && (arg == 1))
  269.         || (token == TEXT && arg == 3)
  270.         || (token == VIDEO || token == IFKEY))
  271.     addstring(ex, string);
  272.     else {
  273.     ex->Code[ex->numcodes].val.i = integer;
  274.     addtoken(ex, INTEGER);
  275.     }
  276. }
  277.  
  278. void
  279. parsefile(ex, ptr)
  280.     ExecStruct *ex;
  281.     char       *ptr;
  282. {
  283.     char        buffer[100];
  284.     int         tokenaddr;
  285.  
  286.     ex->numcodes = 0;
  287.     ex->numlabels = 0;
  288.     do {
  289.     int         i;
  290.     int         token;
  291.  
  292.     ptr = copytoken(ptr, buffer);
  293.     if (buffer[0] == 0)
  294.         break;
  295.     if (buffer[strlen(buffer) - 1] == ':') {
  296.         buffer[strlen(buffer) - 1] = 0;
  297.         addlabel(ex, buffer);
  298.         while (*ptr != '\n' && *ptr != 26)
  299.         ptr++;
  300.     } else {
  301.         int         range;
  302.         int         start;
  303.  
  304.         token = lookuptoken(buffer);
  305.         if (token == NOTOKEN) {
  306.         if (tokentoint(buffer, &i))
  307.             addint(token, 0, ex, buffer, i);
  308.         else
  309.             addstring(ex, buffer);
  310.         tokenaddr = -1;
  311.         } else {
  312.         tokenaddr = ex->numcodes;
  313.         addtoken(ex, token);
  314.         }
  315.  
  316.         range = 0;
  317.         while (*ptr != '\n' && *ptr != 26) {
  318.         int         arg = ex->numcodes - tokenaddr;
  319.         ptr = copytoken(ptr, buffer);
  320.         if (range) {
  321.             if (tokentoint(buffer, &i)) {
  322.             int         val;
  323.             if (i >= start)
  324.                 for (val = start; val <= i; val++)
  325.                 addint(token, arg, ex, buffer, val);
  326.             else
  327.                 for (val = start; val >= i; val--)
  328.                 addint(token, arg, ex, buffer, val);
  329.             range = 0;
  330.             } else
  331.             error("%s: parse error on int range\n");
  332.  
  333.         } else {
  334.             if (buffer[0] == '-' && buffer[1] == 0) {
  335.             range = 1;
  336.             } else {
  337.             if (tokentoint(buffer, &i)) {
  338.                 addint(token, arg, ex, buffer, i);
  339.                 start = i;
  340.             } else
  341.                 addstring(ex, buffer);
  342.             }
  343.         }
  344.         }
  345.         if (tokenaddr != -1)
  346.         addargcount(ex, tokenaddr);
  347.     }
  348.  
  349.     if (*ptr == 26)
  350.         break;
  351.     ptr++;
  352.     } while (*ptr != 26);
  353. }
  354.